package org.jbrisk.IO;

import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.List;

public class IOHelper {

	public static String readFileString(File fileToRead) throws Exception {

		return new String(readFileBytes(fileToRead));
	}

	public static byte[] readFileBytes(File fileToRead) throws Exception {

		// create FileInputStream object
		FileInputStream fin = null;

		try {

			fin = new FileInputStream(fileToRead);

			/*
			 * Create byte array large enough to hold the content of the file.
			 * Use File.length to determine size of the file in bytes.
			 */

			byte fileContent[] = new byte[(int) fileToRead.length()];

			/*
			 * To read content of the file in byte array, use int read(byte[]
			 * byteArray) method of java FileInputStream class.
			 */
			fin.read(fileContent);

			return fileContent;

		} finally {

			if (fin != null) {

				fin.close();
			}
		}
	}

	public static List<File> getFiles(File baseFolder, FilenameFilter filter) {

		List<File> list = new ArrayList<File>();

		getFiles(baseFolder, list, filter);

		return list;
	}

	private static void getFiles(File folder, List<File> list, FilenameFilter filter) {

		folder.setReadOnly();

		File[] files = folder.listFiles();

		for (int j = 0; j < files.length; j++) {

			File file = files[j];

			if (file.isDirectory()) {

				getFiles(file, list, filter);

			} else if (filter == null || filter.accept(file.getParentFile(), file.getName())) {

				list.add(file);
			}
		}
	}

	/*
	 * 

	 */

	/**
	 * Removes the directory and any file inside it.
	 * 
	 * @param directory
	 *            Directory to remove.
	 * @return True if removed everything, false otherwise.
	 */
	public static boolean removeDirectory(File directory) {

		return removeDirectory(directory, true);
	}

	/**
	 * Remove a directory and all of its contents.
	 * 
	 * The results of executing File.delete() on a File object that represents a
	 * directory seems to be platform dependent. This method removes the
	 * directory and all of its contents.
	 * 
	 * @param directory
	 *            The directory to remove.
	 * 
	 * @param removeDirectory
	 *            Indicates if it should remove the directory or only the
	 *            files/directories in it.
	 * 
	 * @return true if the complete directory was removed, false if it could not
	 *         be. If false is returned then some of the files in the directory
	 *         may have been removed.
	 * 
	 * @author Derby - Class org.apache.derby.iapi.util.PropertyUtil
	 * 
	 *         Licensed to the Apache Software Foundation (ASF) under one or
	 *         more contributor license agreements. See the NOTICE file
	 *         distributed with this work for additional information regarding
	 *         copyright ownership. The ASF licenses this file to you under the
	 *         Apache License, Version 2.0 (the "License"); you may not use this
	 *         file except in compliance with the License. You may obtain a copy
	 *         of the License at
	 * 
	 *         http://www.apache.org/licenses/LICENSE-2.0
	 * 
	 *         Unless required by applicable law or agreed to in writing,
	 *         software distributed under the License is distributed on an
	 *         "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
	 *         either express or implied. See the License for the specific
	 *         language governing permissions and limitations under the License.
	 */
	public static boolean removeDirectory(File directory, boolean removeDirectory) {

		boolean removed = false;

		if (directory != null && directory.exists() && directory.isDirectory()) {

			String[] list = directory.list();

			if (list != null) {

				for (int i = 0; i < list.length; i++) {

					File entry = new File(directory, list[i]);

					if (entry.isDirectory()) {
						if (!removeDirectory(entry))
							return false;
					} else {
						if (!entry.delete())
							return false;
					}
				}
			}

			if (removeDirectory)
				removed = directory.delete();
			else
				removed = true;
		}

		return removed;
	}
}
